package Controller;

/**
 * Classe rsponsavel por gerenciar os zumbis. Nesta classe os zumbis sao instanciados assim 
 * como o controle das waves
 * 
 * @author Edjane Catolle, Igor Henrique, Luiz Augusto, Vladmir Chicarolli
 * @version 1.0.0
 * @since 06/05/2011
 */

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import javax.swing.Timer;
import Model.ZombieFactory;
import Model.ZombieFastFactory;
import Model.ZombieFatFactory;
import Model.ZombieHalfFactory;
import Model.ZombieModel;


public class ZombieController extends BaseController implements ActionListener
{
	private List<ZombieModel> zombies = new ArrayList<ZombieModel>();
	private Timer zombieInterval;
	private int zombieDelay = 3500;
	private int waveDelay = 1000;
	private int waveZombies = 10;
	private int currWaveZombies = 0;
	private boolean inTheWave = false;
	
	public ZombieController()
	{
		this.zombieInterval = new Timer(zombieDelay, this);
		this.zombieInterval.setInitialDelay(waveDelay);
	}

	/**
	 * Gera novos zumbis!
	 */
	public void NewWave()
	{
		Random r = new Random();
		int z = r.nextInt(3);
		ZombieFactory factory;
		
		switch (z) 
		{
			case 0:				
				factory = new ZombieFastFactory();
				break;
			case 1:
				factory = new ZombieHalfFactory();
				break;
			default:
				factory = new ZombieFatFactory();
				break;
		}
		
		ZombieModel zombie = factory.CreateZombie();
		zombies.add(zombie);
	}
	
	/**
	 * Lista de zumbis
	 * @return retorna a lista de zumbis na tela
	 */
	public List<ZombieModel> GetZombies()
	{
		return zombies;
	}
	
	/**
	 * Este metodos configura o intervalo de tempo para inicio da WAVE
	 * @param delay - O intervalo de tempo desejado
	 */
	public void SetWaveDelay(int delay)
	{
		this.waveDelay = delay;
	}
	
	/**
	 * Este metodo configura o intervalo de tempo para o aparecimento de cada zumbi
	 * @param delay - O intervalo de tempo desejado
	 */
	public void SetZombieDelay(int delay)
	{
		this.zombieDelay = delay;
	}
	
	/**
	 * Metodo que inicia a WAVE
	 */
	public void startWave()
	{
		this.zombieInterval.start();
	}
	
	/**
	 * Este metodo eh utilizado para configurar quantos zumbis serao criados na WAVE
	 * @param - O numero de zumbis na wave atual
	 */
	public void SetWaveZombies(int zombies)
	{
		this.waveZombies = zombies;
	}
	
	/**
	 * Metodo informa se uma wave esta sendo executada
	 * @return - TRUE se o jogador esta no meio de uma WAVE
	 */
	public boolean isInTheWave()
	{
		return inTheWave;
	}
	
	@Override
	protected void ControllerHandler() 
	{		
		// Zombie movement
		for (ZombieModel zombie : zombies) 
		{
			if(zombie.GetNextStep() != null)
			{
				int x;
				int y;
				
				x = zombie.GetNextStep().GetTileRect().x - zombie.GetPosition().x;
				y = zombie.GetNextStep().GetTileRect().y - zombie.GetPosition().y;
				
				if(x == 0 && y == 0)
				{
					if(zombie.myWay.size() > 0)
					{
						zombie.myWay.remove(zombie.myWay.size() - 1);
					}
				}
				
				if(x != 0)
				{
					zombie.MoveX(x > 0? 1 : -1);
				}
				else
				{
					if(y != 0)
					{
						zombie.MoveY(y > 0? 1 : -1);
					}
				}
			}
		}		
	}

	@Override
	public void HandleKeyboard() 
	{	
		
	}

	/**
	 * Listener utilizado pelo timer para desenhar os zumbis na tela
	 */
	@Override
	public void actionPerformed(ActionEvent timeEvent)
	{
		//System.out.println(currWaveZombies);
		
		if(currWaveZombies <= waveZombies)
		{
			NewWave();
			inTheWave = true;
			currWaveZombies ++;
		}
		else
		{
			zombieInterval.stop();
		}
	}
}
